﻿using System;
using System.Collections.Generic;
using System.IO;
using Engine;
using Game.NetWork;
using Game.NetWork.Packages;
using Game.Server;
using Game.Server.Event;
using Game.Server.PlayerEvent;
using Newtonsoft.Json;

namespace Game.Plugin.MyShopPlugin
{
    public class MyShopPlugin : ServerPlugin, IMessageEventHandle, IPlayerEnterGameEventHandle
    {
        public SubsystemGameInfo SubsystemGameInfo;
        public static Dictionary<string, List<MyShopConfig>> MyShopConfigs = new Dictionary<string, List<MyShopConfig>>();
        public int sloti = 0;
        public override int Version => 10000;
        public override string Name => "我的商店";
        public byte FirstLevel => 0;
        public static string ConfigFilePath => Storage.GetSystemPath("app:/Plugins/MyShopConfig.json");

        // 黑市命令处理器
        private MyShopMarketCmd _marketCmd;

        public override void Initialize()
        {
            MessageEventManager.AddObject(this);
            PlayerEnterGameEventManager.AddObject(this);

            // 只实例化，不重复调用 AddProcessCmdObject（自动注册）
            _marketCmd = new MyShopMarketCmd();
            // 删掉这行
            //CmdManager.AddProcessCmdObject(_marketCmd);
        }

        public string configCreate(string fileName)
        {
            string systemPath = Storage.GetSystemPath("app:/PluginData");
            if (!Directory.Exists(systemPath))
            {
                Directory.CreateDirectory(systemPath);
            }

            string text = "MoneyCoreApi";
            string text2 = Storage.CombinePaths(systemPath, text);
            if (!Directory.Exists(text2))
            {
                Directory.CreateDirectory(text2);
            }

            return Storage.CombinePaths(text2, fileName);
        }

        public override void Load()
        {
            MyShopData.ConfigFilePath = configCreate("PlayerMoney.json");
            MyShopData.Initialize();
            if (GameManager.Project != null) // 增加判断
            {
                SubsystemGameInfo = GameManager.Project.FindSubsystem<SubsystemGameInfo>();
            }
            else
            {
                Log.Warning("插件加载时 GameManager.Project 未初始化，延迟获取 SubsystemGameInfo");
                // 可在 PlayerEnter 事件中再次尝试获取
            }

            try
            {
                MyShopConfigs.Clear();
                if (File.Exists(ConfigFilePath))
                {
                    using (StreamReader streamReader = File.OpenText(ConfigFilePath))
                    {
                        string value = streamReader.ReadToEnd();
                        MyShopConfigs = JsonConvert.DeserializeObject<Dictionary<string, List<MyShopConfig>>>(value);

                        Console.WriteLine("商店配置文件加载成功，内容如下：");
                        Console.WriteLine(value);
                        return;
                    }
                }
                else
                {
                    Console.WriteLine("配置文件不存在，正在创建默认配置文件...");
                    CreateDefaultShopConfig();
                }
            }
            catch (Exception ex)
            {
                Log.Error("插件" + Name + "出现错误" + ex.Message);
            }
        }

        public void CreateDefaultShopConfig()
        {
            var defaultConfig = new Dictionary<string, List<MyShopConfig>>
            {
                {
                    "商店A", new List<MyShopConfig>
                    {
                        new MyShopConfig { shopType = "buy", itemId = 2, count = 1, money = 100, shopLoc = new Point3 { X = 0, Y = 64, Z = 0 } },
                        new MyShopConfig { shopType = "sell", itemId = 2, count = 2, money = 50, shopLoc = new Point3 { X = 0, Y = 64, Z = 1 } },
                        new MyShopConfig { shopType = "sign_in", itemId = 0, count = 86400, money = 100, shopLoc = new Point3 { X = 0, Y = 64, Z = 2 } }
                    }
                }
            };

            string json = JsonConvert.SerializeObject(defaultConfig, Formatting.Indented);

            string directory = Path.GetDirectoryName(ConfigFilePath);
            if (!Directory.Exists(directory))
            {
                Directory.CreateDirectory(directory);
            }

            using (StreamWriter writer = new StreamWriter(ConfigFilePath, false))
            {
                writer.Write(json);
            }

            MyShopConfigs = JsonConvert.DeserializeObject<Dictionary<string, List<MyShopConfig>>>(json);

            Console.WriteLine("商店插件已创建默认配置文件：" + ConfigFilePath);
        }

        public override void Save()
        {
            MyShopData.SaveData();
        }

        public void SendMsg(ComponentPlayer componentPlayer, string text)
        {
            MessagePackage messagePackage = new MessagePackage(null, text, 0, null);
            messagePackage.To = componentPlayer.PlayerData.Client;
            CommonLib.Net.QueuePackage(messagePackage);
        }

        public void ReceiveMessage(string playerName, NetNode netNode, Client From, string message, byte messageType, out bool External)
        {
            External = false;
            // 移除了/n命令的处理，现在由MyShopConfigCmd处理
        }

        public bool IsInvFual(ComponentPlayer componentPlayer, int itemid, int count)
        {
            ComponentInventory componentInventory = componentPlayer.Entity.FindComponent<ComponentInventory>();
            if (componentInventory == null)
            {
                SendMsg(componentPlayer, "<c=red>背包组件未加载，无法操作</c>");
                Log.Warning($"玩家 {componentPlayer.PlayerData.Name} 的背包组件为 null");
                return false;
            }
            for (int i = 0; i < componentInventory.SlotsCount; i++)
            {
                int slotValue = componentInventory.GetSlotValue(i);
                int slotCount = componentInventory.GetSlotCount(i);
                int slotCapacity = componentInventory.GetSlotCapacity(i, itemid);
                if ((slotCount == 0 || slotValue == itemid) && slotCount + count <= slotCapacity)
                {
                    sloti = i;
                    return true;
                }
            }

            return false;
        }

        private bool IsPointNear(Point3 point1, Point3 point2, float tolerance)
        {
            return Math.Abs(point1.X - point2.X) <= tolerance &&
                   Math.Abs(point1.Y - point2.Y) <= tolerance &&
                   Math.Abs(point1.Z - point2.Z) <= tolerance;
        }

        public bool EditSignMessage(Point3 point, ComponentPlayer componentPlayer)
        {
            Console.WriteLine("玩家点击了告示牌，位置：" + point.ToString());
            string playerGuid = componentPlayer.PlayerData.Client.GUID.ToString();

            // 检查是否在编辑模式
            if (MyShopData.IsPlayerInEditMode(playerGuid))
            {
                // 只有在有商店配置的位置才发送消息
                bool hasShopConfig = false;
                foreach (var shopList in MyShopConfigs.Values)
                {
                    foreach (var config in shopList)
                    {
                        if (IsPointNear(config.shopLoc, point, 0.5f))
                        {
                            hasShopConfig = true;
                            break;
                        }
                    }
                    if (hasShopConfig) break;
                }

                if (hasShopConfig)
                {
                    SendMsg(componentPlayer, "<c=yellow>编辑模式：你可以编辑这个告示牌的文字</c>");
                }
                // 如果没有商店配置，不发送任何消息，直接返回true允许编辑
                return true;
            }

            // 检查是否在查看模式
            if (MyShopData.IsPlayerInViewMode(playerGuid))
            {
                string shopInfo = GetShopInfoAtLocation(point);
                if (!string.IsNullOrEmpty(shopInfo))
                {
                    SendMsg(componentPlayer, shopInfo);
                }
                else
                {
                    SendMsg(componentPlayer, "<c=red>该位置没有配置商店</c>");
                }
                return false;
            }

            // 检查是否在删除模式
            if (MyShopData.IsPlayerInDeleteMode(playerGuid))
            {
                DeleteShopAtLocation(point, componentPlayer);
                return false;
            }

            // 检查是否在配置模式
            ShopConfigMode configMode = MyShopData.GetPlayerConfigMode(playerGuid);
            if (configMode != null && configMode.isActive)
            {
                // 配置商店
                ConfigureShop(point, componentPlayer, configMode);
                return false;
            }

            // 正常交易逻辑
            foreach (string key in MyShopConfigs.Keys)
            {
                List<MyShopConfig> list = MyShopConfigs[key];

                foreach (MyShopConfig item in list)
                {
                    if (IsPointNear(point, item.shopLoc, 0.5f))
                    {
                        Console.WriteLine("配置文件中的商店位置：" + item.shopLoc.ToString());

                        // 使用GUID获取玩家数据
                        MyShopListData playerData = MyShopData.GetDataByGuid(playerGuid);
                        if (playerData == null)
                        {
                            // 创建新玩家数据
                            playerData = new MyShopListData
                            {
                                playerMoney = 0.0,
                                lastSignInTime = 0L,
                                playerGuid = playerGuid,
                                playerName = componentPlayer.PlayerData.Name
                            };
                            MyShopData.SetMyShopListDataByGuid(playerGuid, playerData);
                        }

                        if (item.shopType == "buy")
                        {
                            if (!(playerData.playerMoney >= item.money))
                            {
                                SendMsg(componentPlayer, "你的金钱不够买这个物品");
                                return false;
                            }

                            if (IsInvFual(componentPlayer, item.itemId, item.count))
                            {
                                double newMoney = playerData.playerMoney - item.money;
                                MyShopListData newData = new MyShopListData
                                {
                                    playerMoney = newMoney,
                                    playerGuid = playerGuid,
                                    playerName = componentPlayer.PlayerData.Name,
                                    lastSignInTime = playerData.lastSignInTime
                                };
                                MyShopData.SetMyShopListDataByGuid(playerGuid, newData);

                                ComponentInventory componentInventory = componentPlayer.Entity.FindComponent<ComponentInventory>();
                                componentInventory.AddSlotItems(sloti, item.itemId, item.count);
                                SendMsg(componentPlayer, "你成功购买了<c=green>" + item.count + "</c>个物品:<c=green>" + item.itemId + "</c>花费了<c=green>" + item.money + "</c>金币.");
                                return false;
                            }

                            SendMsg(componentPlayer, "你的背包满了");
                            return false;
                        }

                        if (item.shopType == "sell")
                        {
                            ComponentInventory componentInventory2 = componentPlayer.Entity.FindComponent<ComponentInventory>();
                            for (int i = 0; i < componentInventory2.SlotsCount; i++)
                            {
                                int slotCount = componentInventory2.GetSlotCount(i);
                                int slotValue = componentInventory2.GetSlotValue(i);
                                if (slotValue == item.itemId && slotCount >= item.count)
                                {
                                    componentInventory2.RemoveSlotItems(i, item.count);
                                    double newMoney = playerData.playerMoney + item.money;
                                    MyShopListData newData = new MyShopListData
                                    {
                                        playerMoney = newMoney,
                                        playerGuid = playerGuid,
                                        playerName = componentPlayer.PlayerData.Name,
                                        lastSignInTime = playerData.lastSignInTime
                                    };
                                    MyShopData.SetMyShopListDataByGuid(playerGuid, newData);
                                    SendMsg(componentPlayer, "你成功卖出了<c=green>" + item.count + "</c>个物品:<c=green>" + item.itemId + "</c>赚取了<c=green>" + item.money + "</c>金币.");
                                    return false;
                                }
                            }

                            SendMsg(componentPlayer, "你的背包没有需要收购物品或者数量不够");
                            return false;
                        }

                        if (item.shopType == "sign_in")
                        {
                            long currentTime = Convert.ToInt64((DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0)).TotalSeconds);
                            if (currentTime - playerData.lastSignInTime < item.count)
                            {
                                SendMsg(componentPlayer, "<c=red>今天已经签过到了哟!</c>");
                                return false;
                            }

                            MyShopListData newData = new MyShopListData
                            {
                                playerMoney = playerData.playerMoney + item.money,
                                lastSignInTime = currentTime,
                                playerGuid = playerGuid,
                                playerName = componentPlayer.PlayerData.Name
                            };
                            MyShopData.SetMyShopListDataByGuid(playerGuid, newData);
                            SendMsg(componentPlayer, "<c=green>签到成功</c>已获得<c=green>" + item.money.ToString() + "</c>金币.");
                            return false;
                        }
                    }
                }
            }
            return true;
        }

        private void DeleteShopAtLocation(Point3 point, ComponentPlayer componentPlayer)
        {
            string shopNameToDelete = null;
            MyShopConfig configToDelete = null;

            foreach (var shop in MyShopConfigs)
            {
                foreach (var config in shop.Value)
                {
                    if (IsPointNear(config.shopLoc, point, 0.5f))
                    {
                        shopNameToDelete = shop.Key;
                        configToDelete = config;
                        break;
                    }
                }
                if (shopNameToDelete != null) break;
            }

            if (shopNameToDelete != null && configToDelete != null)
            {
                MyShopConfigs[shopNameToDelete].Remove(configToDelete);

                // 如果该商店没有其他配置了，删除整个商店
                if (MyShopConfigs[shopNameToDelete].Count == 0)
                {
                    MyShopConfigs.Remove(shopNameToDelete);
                }

                SaveShopConfig();
                SendMsg(componentPlayer, $"<c=green>已删除位置 ({point.X}, {point.Y}, {point.Z}) 的商店配置</c>");
            }
            else
            {
                SendMsg(componentPlayer, "<c=red>该位置没有配置商店</c>");
            }
        }

        private void ConfigureShop(Point3 point, ComponentPlayer componentPlayer, ShopConfigMode configMode)
        {
            MyShopConfig newConfig = new MyShopConfig
            {
                shopLoc = point,
                shopType = configMode.shopType,
                itemId = configMode.itemId,
                count = configMode.count,
                money = configMode.money,
                shopName = configMode.shopName
            };

            if (!MyShopConfigs.ContainsKey(configMode.shopName))
            {
                MyShopConfigs[configMode.shopName] = new List<MyShopConfig>();
            }

            // 检查是否已存在相同位置的配置
            foreach (var config in MyShopConfigs[configMode.shopName])
            {
                if (IsPointNear(config.shopLoc, point, 0.5f))
                {
                    // 更新现有配置
                    config.shopType = configMode.shopType;
                    config.itemId = configMode.itemId;
                    config.count = configMode.count;
                    config.money = configMode.money;
                    SaveShopConfig();
                    SendMsg(componentPlayer, $"<c=green>已更新该告示牌的商店配置：\n商店名称:{configMode.shopName}\n类型:{configMode.shopType}\n物品ID:{configMode.itemId}\n数量:{configMode.count}\n价格:{configMode.money}</c>");
                    MyShopData.SetPlayerConfigMode(componentPlayer.PlayerData.Client.GUID.ToString(), null);
                    return;
                }
            }

            // 添加新配置
            MyShopConfigs[configMode.shopName].Add(newConfig);
            SaveShopConfig();
            SendMsg(componentPlayer, $"<c=green>已配置商店：\n商店名称:{configMode.shopName}\n类型:{configMode.shopType}\n物品ID:{configMode.itemId}\n数量:{configMode.count}\n价格:{configMode.money}</c>");
            MyShopData.SetPlayerConfigMode(componentPlayer.PlayerData.Client.GUID.ToString(), null);
        }

        private string GetShopInfoAtLocation(Point3 point)
        {
            foreach (var shop in MyShopConfigs)
            {
                foreach (var config in shop.Value)
                {
                    if (IsPointNear(config.shopLoc, point, 0.5f))
                    {
                        return $"<c=yellow>商店名称：{shop.Key}\n类型：{config.shopType}\n物品ID：{config.itemId}\n数量：{config.count}\n价格：{config.money}</c>";
                    }
                }
            }
            return null;
        }

        private void SaveShopConfig()
        {
            try
            {
                string json = JsonConvert.SerializeObject(MyShopConfigs, Formatting.Indented);
                string directory = Path.GetDirectoryName(ConfigFilePath);
                if (!Directory.Exists(directory))
                {
                    Directory.CreateDirectory(directory);
                }
                File.WriteAllText(ConfigFilePath, json);
            }
            catch (Exception ex)
            {
                Log.Error($"保存商店配置失败：{ex.Message}");
            }
        }

        public void PlayerEnter(PlayerData playerData)
        {
            // 检查 playerData 是否为 null（防御性判断）
            if (playerData == null)
            {
                Log.Error("PlayerEnter: playerData 为 null，无法处理玩家进入事件");
                return;
            }

            string name = playerData.Name;
            string playerGuid = null;

            // 检查 Client 是否为 null，避免空引用
            if (playerData.Client == null)
            {
                Log.Warning($"玩家 {name} 的 Client 未初始化，暂时无法获取 GUID");
                return; 
            }

            // 安全获取 GUID
            try
            {
                playerGuid = playerData.Client.GUID.ToString();
            }
            catch (Exception ex)
            {
                Log.Error($"获取玩家 {name} 的 GUID 失败：{ex.Message}");
                return;
            }

            // 使用 playerGuid 处理数据
            if (MyShopData.MyShopListDatas.ContainsKey(playerGuid))
            {
                MyShopListData playerDataObj = MyShopData.MyShopListDatas[playerGuid];
                if (playerDataObj != null)
                {
                    playerDataObj.playerName = name; // 更新玩家名字
                    Console.WriteLine($"玩家 {name} 的数据已加载，当前金钱：{playerDataObj.playerMoney}");
                }
                else
                {
                    // 数据为空时初始化
                    MyShopData.MyShopListDatas[playerGuid] = new MyShopListData
                    {
                        playerMoney = 0.0,
                        lastSignInTime = 0L,
                        playerGuid = playerGuid,
                        playerName = name
                    };
                }
            }
            else
            {
                // 数据不存在时初始化
                MyShopData.MyShopListDatas.Add(playerGuid, new MyShopListData
                {
                    playerMoney = 0.0,
                    lastSignInTime = 0L,
                    playerGuid = playerGuid,
                    playerName = name
                });
            }
        }

        public void PlayerLeave(PlayerData playerData)
        {
        }
    }
}
